﻿using LibGit2Sharp;
using ProjectManager.Interface;
using ProjectManager.Logic.Content;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;

namespace ProjectManager.Controller
{
    internal partial class GitController : IGit
    {
        private UsernamePasswordCredentials CredentialsProvider(string _url, string _user, SupportedCredentialTypes _cred)
        {
            var np = LocalFileController.GetUsernamePassword(_url);
            return new UsernamePasswordCredentials()
            {
                Username = np.Item1,
                Password = np.Item2,
            };
        }
        // 开源仓库
        public void Clone(string url, string path, string branchName = "master")
        {
            CloneOptions options = new CloneOptions()
            {
                BranchName = branchName,
            };
            options.FetchOptions.CredentialsProvider = CredentialsProvider;
            try
            {
                Repository.Clone(url, path, options);
            }
            catch (NameConflictException) { }
        }
        public void CreateBranch(string repoPath, string branchName)
        {
            using var repo = new Repository(repoPath);
            Console.WriteLine(repo.Branches.Select(b => b.FriendlyName).ToList());
            if (repo.Branches.Select(b => b.FriendlyName).Contains($"origin/{branchName}"))
                return;
            // 获取master分支
            var currentBranch = repo.Branches["master"];
            // 创建新分支
            var newBranch = repo.CreateBranch(branchName, currentBranch.Tip);
            // 推送到远程仓库
            Remote repoRemote = repo.Network.Remotes["origin"];
            PushOptions pushOptions = new PushOptions()
            {
                CredentialsProvider = CredentialsProvider,
            };
            repo.Network.Push(repoRemote, $"refs/heads/{newBranch.FriendlyName}", pushOptions);
        }
        public void Commit(string repoPath, string branchName
            , string commitName, string commitDescription
            , string name="PM", string email="PM@pm.com")
        {
            using var repo = new Repository(repoPath);
            // 获取当前分支
            var branch = repo.Branches[branchName];
            // 创建提交
            Identity identity = new(name, email);
            var signature = new Signature(identity, DateTime.Now);
            // 提交所有更改
            Commands.Stage(repo, "*");
            var commitMessage = commitDescription;
            try
            {
                var commit = repo.Commit(commitMessage, signature, signature);
            }
            catch (EmptyCommitException) { }
        }
        public void Push(string repoPath, string branchName)
        {
            using var repo = new Repository(repoPath);
            var branch = repo.Branches[branchName];
            PushOptions pushOptions = new PushOptions()
            {
                CredentialsProvider = CredentialsProvider
            };
            repo.Network.Push(branch, pushOptions);
        }
        public void Pull(string repoPath, string branchName
            , string name = "PM", string email = "PM@pm.com")
        {
            // fetch
            try
            {
                using var repo = new Repository(repoPath);
                var remote = repo.Network.Remotes["origin"];
                var refSpecs = remote.FetchRefSpecs.Select(x => x.Specification);
                FetchOptions fetchOptions = new FetchOptions()
                {
                    CredentialsProvider = CredentialsProvider,
                };
                repo.Network.Fetch("origin", refSpecs, fetchOptions);

                // merge
                Signature merger = new Signature(name, email, DateTime.Now);
                repo.Merge(repo.Branches[$"origin/{branchName}"], merger);
            }
            catch (RepositoryNotFoundException)
            {
                return;
            }
        }
        public List<string> GetCommitMessages(string repoPath, string branchName)
        {
            using var repo = new Repository(repoPath);
            var branch = repo.Branches[branchName];
            return branch.Commits.Select(x => x.Message).ToList();
        }
    }
}
